package es.ise.core.mbg.plugins.constraints;

import java.util.List;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.TopLevelClass;

/**
 * Este plugin examina la metainformación de las columnas para comprobar cuales
 * pueden ser nulas y cuales no, y establece validaciones JSR-303 para cada una
 * de ellas.
 * 
 * Si la columna es de tipo cadena, se establecerá la validación &#064;NotEmpty de
 * Hibernate Validator, que comprueba también si la cadena no es vacía, ya que
 * Oracle considera las cadenas vacías como nulas.
 * 
 * Estas restricciones solo se tienen en cuenta en tablas con claves primarias. Si
 * no las tiene se supone que es una vista, donde carece de sentido tener validaciones
 * en los campos.
 * 
 * @author Paco
 *
 */
public class NullConstraintPlugin extends PluginAdapter
{

	@Override
	public boolean validate(List<String> warnings)
	{
		// no validations needed
		return true;
	}

	@Override
	public boolean modelFieldGenerated(Field field, TopLevelClass clazz, IntrospectedColumn column, IntrospectedTable table, ModelClassType modelClassType)
	{
		if(table.hasPrimaryKeyColumns()) // si la table tiene claves primarias...
		{
			if(!column.isNullable()) // y la columna no puede ser nula
			{
				if(column.isJdbcCharacterColumn() || column.isStringColumn())
				{
					// si es de tipo cadena añadimos la validación @NotEmpty
					clazz.addImportedType(new FullyQualifiedJavaType("org.hibernate.validator.constraints.NotEmpty"));
					field.addAnnotation("@NotEmpty");
				}
				else
				{
					// en otro caso, añadimo las estándar @NotNull
					clazz.addImportedType(new FullyQualifiedJavaType("javax.validation.constraints.NotNull"));
					field.addAnnotation("@NotNull");
				}
			}
		}
		return true;
	}

}
